function dedupe(array) {
  if (!Array.isArray(array)) {
    console.log("type error!");
    return;
  }
  return Array.from(new Set(array));
}
console.log(dedupe([1, 2, 3, 4, 5, 5, 6, 5, 5]));

// 去除数组的重复成员
const array = [1, 2, 3, 4, 5, 5, 6, 5, 5];
// console.log([...new Set(array)]);
function unique(array) {
  if (!Array.isArray(array)) {
    console.log("type error!");
    return;
  }
  return [...new Set(array)];
}
console.log(unique(array));
//console.log([...new Set(array)].join(''))  //转字符串

//Set 对象个数
// const set = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
// console.log([...set])
const items = new Set([1, 2, 3, 4, 5, 5, 6, 5, 5]);
//console.log(items.size); // 5  对象个数

const s = new Set();
const a = [];
[1, 2, 3, 4, 5, 5, 6, 5, 5].forEach((x) => s.add(x));
for (let i of s) {
  a.push(i);
  // console.log(i);
}
console.log(a);

//双循环去重
let arr = [1, 2, 3, 4, 5, 5, 6, 5, 5];
function unique(arr) {
  if (!Array.isArray(arr)) {
    console.log("type error!");
    return;
  }
  let res = [arr[0]];
  for (let i = 1; i < arr.length; i++) {
    let flag = true;
    for (let j = 0; j < res.length; j++) {
      if (arr[i] === res[j]) {
        flag = false;
        break;
      }
    }
    if (flag) {
      res.push(arr[i]);
    }
  }
  return res;
}
console.log(unique(arr));

//相邻元素去重
function adjacent(arr) {
  if (!Array.isArray(arr)) {
    console.log("type error!");
    return;
  }
  arr = arr.sort();
  let res = [];
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] !== arr[i - 1]) {
      res.push(arr[i]);
    }
  }
  return res;
}
console.log(adjacent([1, 2, 3, 4, 5, 5, 6, 5, 5]));

//求交集
let data1 = [1, 2, 3, 4, 5, 6];
let datas1 = [6, 5, 3, 4];

// const data1 = data.map(item=>item.id)
// const datas1 = datas.map(item=>item.id)
const inter = data1.filter((item) => datas1.includes(item));
console.log(inter);
const inters = datas1.filter((item) => data1.includes(item));
console.log(inters);

//对象排序
let d = arr.sort(compare("time", true)); //time:排序的依据属性
console.log(d);
/** 两个参数： 参数1 是排序用的字段， 参数2 是：是否升序排序 true 为升序，false为降序*/
function compare(attr, rev) {
  if (rev == undefined) {
    rev = 1;
  } else {
    rev = rev ? 1 : -1;
  }
  return (a, b) => {
    a = a[attr];
    b = b[attr];
    if (a < b) {
      return rev * -1;
    }
    if (a > b) {
      return rev * 1;
    }
    return 0;
  };
}

//防抖（debounce）:当持续触发事件时，保证只执行最后一次事件处理函数
function debounce(fn) {
  let timeout = null; //创建一个标记用来存放定时器的返回值
  return function () {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      fn();
    }, 500);
  };
}
function sayhi() {
  console.log("防抖成功");
}
let box = document.getElementById("box");
box.addEventListener("click", debounce(sayhi));
/*在给DOM绑定事件时，有些事件我们是无法控制触发频率的。 如鼠标移动事件onmousemove, 滚动滚动条事件onscroll，窗口大小改变事件onresize，瞬间的操作都会导致这些事件会被高频触发。 如果事件的回调函数较为复杂，就会导致响应跟不上触发，出现页面卡顿，假死现象。 在实时检查输入时，如果我们绑定onkeyup事件发请求去服务端检查，用户输入过程中，事件的触发频率也会很高，会导致大量的请求发出，响应速度会大大跟不上触发。
如何实现防抖呢?
我们拿滚动事件举例子，用户的滚动会频繁触发滚动事件，很容易造成页面卡死。那么我们可以封装如下一个函数。每次想调用函数的时候，设置一个定时器让函数延迟执行。当连续触发的时候，前面每次定时器都会清除掉,都会停掉前面的定时器所以函数并不会运行，只会执行最后一次。 */

//节流（throttle）：：当持续触发事件时，保证一定时间段内只调用一次事件处理函数
function throttle(fn) {
  let canRun = true; //通过闭包保存一个标记
  return function () {
    if (!canRun) return; //在函数开头判断标记是否为true,不为true则return
    CanRun = false; //立即设置为false
    setTimeout(() => {
      //将外部传入的函数的执行放在setTimeout中
      fn();
      //最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
      canRun = true;
    }, 500);
  };
}
function sayhi(e) {
  console.log("节流");
}
window.addEventListener("resize", throttle(sayHi));
/* 节流通俗解释就比如我们水龙头放水，阀门一打开，水哗哗的往下流，秉着勤俭节约的优良传统美德，我们要把水龙头关小点，最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。
如何实现节流？
当用户连续操作的时候，我们设置一个定时器，一段时间后执行函数，并且执行完把标记改为true，所以在函数没有执行完之前一直是false，可能有的同学认为连续操作那么函数连续运行，那么canRun这个标记不一直是true吗，并不是，注意这里是一个闭包结构，真正每次调用的其实是throttle里面return的函数并不是每次都调用throttle，所以canRun只是提供初始值，并不会每次都重新赋值为true。所以用户连续操作的时候，比如用户一秒钟连续操作了十次，但是对于我们这个代码来说，只可能每500毫秒执行一次，因为只有500ms之后canRun才为true，才能开启下一个定时器。所以哪怕用户一秒钟之内连续点了十次，其实也只是能执行两次。这就符合节流的本意。
*/
